﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Data.Objects;
using System.ComponentModel;

namespace RL
{
    class RouteListLogic
    {
        public routelistEntities ContextDB { get; set; }

        private RouteList _RouteList;

        public RouteList RouteList
        {
            get
            { return _RouteList; }
            set
            {
                _RouteList = value;
            }
        }

        public double? FuelNorm { get; set; }



        public double VokzalSum { get; set; }      

        private ObjectQuery<RouteListSchedule> getScheduleRL(RouteList rl)
        {
            if (null == _RouteList) return null;
            ObjectQuery<RouteListSchedule> result = ContextDB.RouteListSchedule.Where("it.id_rl=@prm", new ObjectParameter("prm", rl.id));
            return result;
        }

        private ObjectQuery<RouteListInfo> getRouteListInfo(RouteList rl)
        {
            if (null == _RouteList) return null;
            ObjectQuery<RouteListInfo> result = ContextDB.RouteListInfo.Where("it.id_rl=@prm", new ObjectParameter("prm", rl.id));
            return result;
        }

        public ObjectQuery<RouteTable> getSchedule(int numDeparture, DateTime dt)
        {
            ObjectQuery<RouteTable> result = null;
            if (null == ContextDB) return result;
            DayOfWeek dw = dt.DayOfWeek;
            StringBuilder strq = new StringBuilder();
            strq.Append("SELECT VALUE RouteTable FROM routelistEntities.Routetable as Routetable JOIN routelistEntities.Schedule as Schedule ON RouteTable.id_schedule==Schedule.id WHERE ");
            strq.Append(string.Format("RouteTable.numberDeparture={0}", numDeparture));
            strq.Append(" AND ");
            switch (dw)
            {
                case DayOfWeek.Monday:
                    strq.Append("Schedule.monday==true");
                    break;
                case DayOfWeek.Tuesday:
                    strq.Append("Schedule.tuesday==true");
                    break;
                case DayOfWeek.Wednesday:
                    strq.Append("Schedule.wednesday==true");
                    break;
                case DayOfWeek.Thursday:
                    strq.Append("Schedule.thursday==true");
                    break;
                case DayOfWeek.Friday:
                    strq.Append("Schedule.friday==true");
                    break;
                case DayOfWeek.Saturday:
                    strq.Append("Schedule.saturday==true");
                    break;
                case DayOfWeek.Sunday:
                    strq.Append("Schedule.sunday==true");
                    break;
            }

            result = new ObjectQuery<RouteTable>(strq.ToString(), ContextDB);
            return result;
        }

        private void ClearRouteTable()
        {
            if (null == ContextDB) return;
            if (null == RouteList) return;

            var rli = (from o in RouteList.RouteListInfo select o).ToList();
            foreach (RouteListInfo item in rli)
            {
                ContextDB.DeleteObject(item);
            }
            var rsc = (from o in RouteList.RouteListSchedule select o).ToList();
            foreach (RouteListSchedule item in rsc)
            {
                ContextDB.DeleteObject(item);
            }
            RouteList.departure = "";
            RouteList.arrive = "";
            RouteList.total_length = null;
            RouteList.total_free_length = null;
            RouteList.total_reis_plan = null;
            RouteList.total_free_fact = null;
            RouteList.total_work_time = null;
            RouteList.total_rest_time = null;
            RouteList.sum_plan = null;
            RouteList.sum_fact = null;
            RouteList.total_workt_fact = null;
            RouteList.total_restt_fact = null;
            RouteList.id_RouteTable = null;
        }

        private void ClearFuelData()
        {
            FuelNorm = null;
        }

        public double CalcVokzalTableSum()
        {
            double result = 0;
            try
            {
                if (null == RouteList) return result;
                var q = from o in RouteList.VokzalTable where o.del==false select o.summa_tickets + o.bagazh;
                result = q.Sum();
            }
            catch (Exception)
            {
            }
            return result;
        }

        public double CalcVokzalTableInsurance()
        {
            double result = 0;
            try
            {
                if (null == RouteList) return result;
                var q = from o in RouteList.VokzalTable where o.del==false select o.sum_insurance;
                result = q.Sum();
            }
            catch (Exception)
            {
            }
            return result;
        }

        private void LoadFuelData()
        {
            if (null == RouteList.vehicle) return;
            try
            {
                var vehicle_norm = (from o in RouteList.vehicle.vehicle_type.FuelVehicleTypeNorm select o).FirstOrDefault();
                if (null == vehicle_norm) return;
                FuelNorm = RouteList.total_length / 100 * vehicle_norm.expense_norm;
                FuelNorm = Math.Round(FuelNorm.Value, 1);
            }
            catch (Exception)
            {
            }
        }

        public void LoadRouteTable(int id)
        {
            float alt_plan=0;
            if (null == ContextDB) return;
            if (null == RouteList) return;
            //if (RouteList.id_RouteTable == id) return;
            ClearRouteTable();
            ClearFuelData();
            RouteTable rt = (from o in ContextDB.RouteTable where o.id == id select o).FirstOrDefault();
            if (null == rt) return;
            RouteList.departure = rt.departure;
            RouteList.arrive = rt.arrive;
            RouteList.total_length = rt.total_length;
            RouteList.total_free_length = rt.total_free_length;
            RouteList.total_reis_plan = rt.total_reis;
            RouteList.total_free_fact = rt.total_reis;
            RouteList.total_work_time = rt.total_work_time;
            RouteList.total_rest_time = rt.total_rest_time;
            RouteList.sum_plan = rt.sum_plan;
            RouteList.sum_fact = 0;
            RouteList.total_workt_fact = rt.total_work_time;
            RouteList.total_restt_fact = rt.total_rest_time;
            RouteList.id_RouteTable = id;

            // Определяем план, итоговый для каждого дня недели
            if (RouteList.dt_datedoc.HasValue)
            {
                DayOfWeek dw = RouteList.dt_datedoc.Value.DayOfWeek;
                RoutePlan rplan = (from o in rt.RoutePlan where o.id_route == null select o).FirstOrDefault();
                if (null != rplan)
                {
                    switch (dw)
                    {
                        case DayOfWeek.Monday:
                            alt_plan = rplan.monday;
                            break;
                        case DayOfWeek.Tuesday:
                            alt_plan = rplan.tuesday;
                            break;
                        case DayOfWeek.Wednesday:
                            alt_plan = rplan.wednesday;
                            break;
                        case DayOfWeek.Thursday:
                            alt_plan = rplan.thursday;
                            break;
                        case DayOfWeek.Friday:
                            alt_plan = rplan.friday;
                            break;
                        case DayOfWeek.Saturday:
                            alt_plan = rplan.saturday;
                            break;
                        case DayOfWeek.Sunday:
                            alt_plan = rplan.sunday;
                            break;
                    }
                    if (0 != alt_plan)
                    {
                        RouteList.sum_plan = alt_plan;
                    }
                }
            }
            IEnumerable<RouteDepartureCharact> rdc = from o in rt.RouteDepartureCharact orderby o.Routes.number select o;
            foreach (RouteDepartureCharact item in rdc)
            {
                RouteListInfo additem = new RouteListInfo();
                additem.id_route = item.id_route;
                additem.price = item.column_2;
                additem.length = item.length;
                additem.free_length = item.free_length;
                additem.reis = item.reis;
                additem.WORK_TIME = item.work_time;
                additem.rest_time = item.rest_time;
                additem.reis_fact = item.reis;
                additem.length_fact = item.length;
                additem.free_length_fact = item.free_length;
                RouteList.RouteListInfo.Add(additem);
            }
            IEnumerable<RouteDepartureSchedule> rds = from o in rt.RouteDepartureSchedule orderby o.time_departure.Trim() + o.time_arrive.Trim() select o;
            foreach (RouteDepartureSchedule item in rds)
            {
                RouteListSchedule additem = new RouteListSchedule();
                additem.id_route = item.id_route;
                additem.name_busstop = item.name_busstop;
                additem.time_arrive = item.time_arrive;
                additem.time_departure = item.time_departure;
                RouteList.RouteListSchedule.Add(additem);
            }
        }

        private string ShortFIO(string fio)
        {
            if (string.IsNullOrEmpty(fio)) return fio;
            StringBuilder result = new StringBuilder();
            try
            {
                string[] fio_s = fio.Trim().Split(' ');
                result.Append(string.Format("{0} ", fio_s[0]));
                if (fio_s.Count() > 1)
                {
                    result.Append(string.Format("{0}.", fio_s[1].Substring(0, 1)));
                }
                if (fio_s.Count() > 2)
                {
                    result.Append(string.Format("{0}.", fio_s[2].Substring(0, 1)));
                }
            }
            catch (Exception)
            {
            }
            return result.ToString();
        }

        public ReportRL GetRLTable()
        {
            int i;
            string propname;
            string sval;
            if (null == RouteList) return null;
            ReportRL it = new ReportRL();
            try
            {
                Enterprise ent = (from o in ContextDB.Enterprise select o).FirstOrDefault();
                if (null != ent)
                {
                    it.enterprise = ent.enterprise_name;
                    it.address = ent.address;
                    it.OKPO = ent.okpo;
                    it.phone = ent.phone;
                    it.dispetcher = ShortFIO(ent.person.fio);
                    it.mechanic = ShortFIO(ent.person1.fio);
                }
            }
            catch (Exception)
            {
            }
            try
            {

                it.nomdoc = RouteList.nomdog.Trim();
                if (it.nomdoc.Count() > 7)
                    it.nomdoc = it.nomdoc.Substring(3);
                //it.datedoc = RouteList.datedoc;
                if (RouteList.dt_datedoc.HasValue)
                    it.datedoc = RouteList.dt_datedoc.Value.ToString("dd/MM/yyyy");
                else
                    it.datedoc = "";
                if (RouteList.nomdeparture.HasValue)
                    it.departure = RouteList.nomdeparture.ToString(); 
            }
            catch (Exception)
            {
            }
            try
            {
                it.driver = RouteList.driver.person.fio.Trim();
                it.tabel = RouteList.driver.person.tabel.Trim();
                it.driver_short = ShortFIO(it.driver);
                it.driver_license = RouteList.driver.license_number;
            }
            catch (Exception)
            {
            }

            try
            {
                int qnt_pass;
                int qnt_tot_pass;
                it.vehicle_gar_number = RouteList.vehicle.gar_number;
                it.vehicle_gos_number = RouteList.vehicle.gos_number;
                it.bus_passenger = RouteList.vehicle.qnt_passenger.ToString();
                it.bus_passenger = RouteList.vehicle.qnt_total_passenger.ToString();
                it.license_serial = RouteList.vehicle.license_reg_serial;
                it.license_number = RouteList.vehicle.license_reg_number;
                it.license = RouteList.vehicle.license_number;
                it.vehicle_model = RouteList.vehicle.vehicle_type.name.Trim();
                LoadFuelData();
                it.fuel_norm = FuelNorm.HasValue ? FuelNorm.Value.ToString() : "";
                try
                {
                    qnt_pass = RouteList.vehicle.qnt_passenger;
                    qnt_tot_pass = RouteList.vehicle.qnt_total_passenger;
                    qnt_pass = qnt_pass == 0 ? RouteList.vehicle.vehicle_type.qnt_passenger : qnt_pass;
                    qnt_tot_pass = qnt_tot_pass == 0 ? RouteList.vehicle.vehicle_type.qnt_total_passenger : qnt_tot_pass;
                    it.bus_total_passenger = qnt_tot_pass.ToString();
                    it.bus_passenger = qnt_pass.ToString();
                } catch(Exception)
                {
                }
                it.work_time = RouteList.total_work_time.ToString();
                it.rest_time = RouteList.total_rest_time.ToString();
            }
            catch (Exception)
            {

            }

            it.time_arrive = RouteList.arrive;
            it.time_departure = RouteList.departure;

            try
            {
                it.reis = RouteList.total_reis_plan.ToString();
                it.plan = RouteList.sum_plan.ToString();
                it.length_total = RouteList.total_length.ToString();
                it.length_free = RouteList.total_free_length.ToString();
            }
            catch (Exception)
            {
            }

            try
            {
                IEnumerable<RouteListSchedule> qSchedule = from o in RouteList.RouteListSchedule orderby o.time_departure.Trim() + o.time_arrive.Trim() select o;
                i = 0;
                foreach (RouteListSchedule item in qSchedule)
                {

                    i++;
                    try
                    {
                        propname = string.Format("sch_route{0}", i);
                        //sval = string.Format("{0} {1}", item.Routes.number.ToString(), item.Routes.name.ToUpper().Trim());
                        sval = string.Format("{0} {1}", item.Routes.number.ToString(), item.name_busstop.ToUpper().Trim());
                        it.GetType().GetProperty(propname).SetValue(it, sval, null);
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("arrive{0}", i);
                        sval = item.time_arrive;
                        it.GetType().GetProperty(propname).SetValue(it, sval, null);
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("departure{0}", i);
                        sval = item.time_departure;
                        it.GetType().GetProperty(propname).SetValue(it, sval, null);
                    }
                    catch (Exception)
                    {
                    }
                    if (i > 29) break;
                }
            }
            catch (Exception)
            {
            };

            try
            {
                IEnumerable<RouteListInfo> qInfo = from o in RouteList.RouteListInfo orderby o.Routes.number select o;
                i = 0;
                foreach (RouteListInfo item in qInfo)
                {
                    i++;
                    try
                    {
                        propname = string.Format("info_route{0}", i);
                        sval = string.Format("{0} {1}", item.Routes.number.ToString(), item.Routes.name.ToUpper().Trim());
                        it.GetType().GetProperty(propname).SetValue(it, sval, null);
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("price{0}", i);
                        if (item.price.HasValue)
                        {
                            sval = item.price.ToString();
                            it.GetType().GetProperty(propname).SetValue(it, sval, null);
                        }
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("length{0}", i);
                        if (item.length.HasValue)
                        {
                            sval = item.length.ToString();
                            it.GetType().GetProperty(propname).SetValue(it, sval, null);
                        }
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("length_zero{0}", i);
                        if (item.free_length.HasValue)
                        {
                            sval = item.free_length.ToString();
                            it.GetType().GetProperty(propname).SetValue(it, sval, null);
                        }
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("work_time{0}", i);
                        if (item.WORK_TIME.HasValue)
                        {
                            sval = item.WORK_TIME.ToString();
                            it.GetType().GetProperty(propname).SetValue(it, sval, null);
                        }
                    }
                    catch (Exception)
                    {
                    }

                    try
                    {
                        propname = string.Format("reis_plan{0}", i);
                        if (item.reis.HasValue)
                        {
                            sval = item.reis.ToString();
                            it.GetType().GetProperty(propname).SetValue(it, sval, null);
                        }
                    }
                    catch (Exception)
                    {
                    }
                    if (i > 21) break;

                }
            }
            catch (Exception)
            {
            }
            return it;
        }
    }
}
